package com.sf.osms.dep.processor.util;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.sf.osms.dep.processor.model.XmlRecord;
import com.sf.osms.dep.processor.parser.xml.annotation.XmlType;

public class XMLParserUtils {
	public final static String FILE_PATH = "/CONSIGNMENT";
	public static int i=0;
	public static String beanToXml(Object obj) throws Exception{
		 JAXBContext jc = JAXBContext.newInstance(obj.getClass());
		 Marshaller marshaller = jc.createMarshaller();
		 marshaller.marshal(obj, System.out);
		return null;
	}
	
	/**
	 * 映射xml到bean
	 * @param filePath 文件路径
	 * @param objectNode 数据节点的xpath路径
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
    public static <T> List<T> xmlTobean(String filePath,String objectNode,Class<T> clazz) throws Exception{
    	
    	if(StringUtils.isBlank(filePath) || StringUtils.isBlank(objectNode) || null == clazz){
    		return null;
    	}
    	
    	//找到所有的映射关系,xml中解析关系和实体类中字段信息
    	Map<String,String> fieldRules = new HashMap<String,String>();
    	Field[] fields = clazz.getDeclaredFields();
    	for (Field field : fields) {
			XmlType annotation = field.getAnnotation(XmlType.class);
			if(null != annotation){
				fieldRules.put(annotation.value().trim(),field.getName());
			}else{
				fieldRules.put(field.getName(),field.getName());
			}
			
		}
    	Set<String> keySets = fieldRules.keySet();
    	
    	 // 创建saxReader对象  
        SAXReader reader = new SAXReader();  
        // 通过read方法读取一个文件 转换成Document对象  
        Document doc = reader.read(filePath);  
    	List<Element> nodes = doc.selectNodes(objectNode); //得到所有的数据节点
    	
    	if(CollectionUtil.isEmpty(nodes)){
    		//FIXME:日志
    		return null;
    	}
    	
    	List<T> list = new ArrayList<T>();
    	
    	for (Element node : nodes) {
			T bean = clazz.newInstance();
			//首先进行必要数据的填充
			List<Element> headers = node.selectNodes(".//CNHEADER");
			if(CollectionUtil.isEmpty(headers)){
				continue;
			}
			Element header = headers.get(0); //若多个取第一个
			//进行header数据的填充
			for (String key : keySets) {
				List<Element> selectNodes = header.selectNodes(".//FIELD[@NAME=\""+key+"\"]");
				if(CollectionUtil.isEmpty(selectNodes)){
					continue;
				}
				
				String value = selectNodes.get(0).attributeValue("VALUE");
				if(StringUtils.isNotBlank(value)){
					//对于80节点数据bardate和bartime的特殊处理
					if("strStatusTransOn".equalsIgnoreCase(key.trim())){
						ReflectUtils.setFiledValue(bean, "strActionDate", value);
					}else if("strStatusTransTime".equalsIgnoreCase(key.trim())){
						ReflectUtils.setFiledValue(bean, "strActionTime", value);
					}else{
						ReflectUtils.setFiledValue(bean, fieldRules.get(key), value);
					}
					
				}
				
			}
			
			/**
			 * 进行80节点的判断
			 */
			if("DELIVERED".equalsIgnoreCase((String) ReflectUtils.getFieldValue(bean, "strStatus"))){
				ReflectUtils.setFiledValue(bean,"strAction","80");
				list.add(bean);//进行数据的添加
				continue;
			}
		
			List<Element> bodys = node.selectNodes(".//CNACTION");
			if(CollectionUtil.isEmpty(bodys)){
				continue; //没有则不添加记录
			}
			
			for(int i=0;i<bodys.size();i++){
					T newBean = DozerSingleton.getMapper().map(bean, clazz);
					Element body = bodys.get(i);
					for (String key : keySets) {
						List<Element> selectNodes = body.selectNodes(".//FIELD[@NAME=\""+key+"\"]");
						if(CollectionUtil.isEmpty(selectNodes)){
							continue;
						}
						
						String value = selectNodes.get(0).attributeValue("VALUE");
						if(StringUtils.isNotBlank(value)){
							ReflectUtils.setFiledValue(newBean, fieldRules.get(key), value);
						}
						
					}
					list.add(newBean);
				
			}
			
			
		}
    	
    	return list;
    }
    /**
	 * 映射xml到bean
	 * @param filePath 文件路径
	 * @param objectNode 数据节点的xpath路径
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
    public static <T> List<T> xmlTobean(File file,String objectNode,Class<T> clazz) throws Exception{
    	
    	if(null == file || StringUtils.isBlank(objectNode) || null == clazz){
    		return null;
    	}
    	
    	//找到所有的映射关系,xml中解析关系和实体类中字段信息
    	Map<String,String> fieldRules = new HashMap<String,String>();
    	Field[] fields = clazz.getDeclaredFields();
    	for (Field field : fields) {
			XmlType annotation = field.getAnnotation(XmlType.class);
			if(null != annotation){
				fieldRules.put(annotation.value().trim(),field.getName());
			}else{
				fieldRules.put(field.getName(),field.getName());
			}
			
		}
    	Set<String> keySets = fieldRules.keySet();
    	
    	 // 创建saxReader对象  
        SAXReader reader = new SAXReader();  
        // 通过read方法读取一个文件 转换成Document对象  
        Document doc = reader.read(file);  
    	List<Element> nodes = doc.selectNodes(objectNode); //得到所有的数据节点
    	
    	if(CollectionUtil.isEmpty(nodes)){
    		//FIXME:日志
    		return null;
    	}
    	
    	List<T> list = new ArrayList<T>();
    	
    	for (Element node : nodes) {
			T bean = clazz.newInstance();
			//首先进行必要数据的填充
			List<Element> headers = node.selectNodes(".//CNHEADER");
			if(CollectionUtil.isEmpty(headers)){
				continue;
			}
			Element header = headers.get(0); //若多个取第一个
			//进行header数据的填充
			for (String key : keySets) {
				List<Element> selectNodes = header.selectNodes(".//FIELD[@NAME=\""+key+"\"]");
				if(CollectionUtil.isEmpty(selectNodes)){
					continue;
				}
				
				String value = selectNodes.get(0).attributeValue("VALUE");
				if(StringUtils.isNotBlank(value)){
					//对于80节点数据bardate和bartime的特殊处理
					if("strStatusTransOn".equalsIgnoreCase(key.trim())){
						value = value.substring(4) + value.substring(2, 4) + value.substring(0, 2);
						ReflectUtils.setFiledValue(bean, "strActionDate", value);
					}else if("strStatusTransTime".equalsIgnoreCase(key.trim())){
						//进行补0操作
						ReflectUtils.setFiledValue(bean, "strActionTime", StringUtil.repairStrLen(value,'0',4));
					}else{
						ReflectUtils.setFiledValue(bean, fieldRules.get(key), value);
					}
				}
				
			}
			
			/**
			 * 进行80节点的判断
			 */
			if("DELIVERED".equalsIgnoreCase((String) ReflectUtils.getFieldValue(bean, "strStatus"))){
				ReflectUtils.setFiledValue(bean,"strAction","80");
				list.add(bean);//进行数据的添加
			}
		
			List<Element> bodys = node.selectNodes(".//CNACTION");
			if(CollectionUtil.isEmpty(bodys)){
				continue;
			}	
			for(int i=0;i<bodys.size();i++){
					T newBean = DozerSingleton.getMapper().map(bean, clazz);
					Element body = bodys.get(i);
					for (String key : keySets) {
						List<Element> selectNodes = body.selectNodes(".//FIELD[@NAME=\""+key+"\"]");
						if(CollectionUtil.isEmpty(selectNodes)){
							continue;
						}
						
						String value = selectNodes.get(0).attributeValue("VALUE");
						if(StringUtils.isNotBlank(value)){
							if("strActionDate".equals(key)){
								value = value.substring(4) + value.substring(2, 4) + value.substring(0, 2);
							}
							if("strActionTime".equals(key)){
								value = StringUtil.repairStrLen(value,'0',4);
							}
							ReflectUtils.setFiledValue(newBean, fieldRules.get(key), value);
						}
						
					}
					list.add(newBean);
				
			}
			
			
		}
    	
    	return list;
    }
    public static void main(String[] args) throws Exception{
    	File file = new File("E:/DTDC_TRACK_120716_0800.xml");
		List<XmlRecord> xmlTobeans = xmlTobean(file,"/DTDCREPLY//CONSIGNMENT", XmlRecord.class);
		for (XmlRecord xmlRecord : xmlTobeans) {
			System.out.println(xmlRecord);
		}
		System.out.println(xmlTobeans.size());
		String value = "13072016";
		value = value.substring(4) + value.substring(2, 4) + value.substring(0, 2);
		System.out.println(value);
	}
}
